import LXCOM from '../common/common.js'
import baseunitgrah from './baseunitgrah.js'
import { CoordTRFUtil } from '../common/tools/coordtool.js'
import ActPkg from './action/textaction.js'
import Coord from '../common/struct/coord.js'
import { LGXEnums } from '../common/sysenum.js'

import globalConst from '../common/globalConst.js'
var global = globalConst.GlobalConst;
import textinfo from '../common/struct/basestruct/textinfo.js'

import UtilFuncs from '../common/tools/utilfuncs.js'
var funcs = UtilFuncs.UtilFuncs;

import { GlobalVar } from '../common/globalvar.js'
import { Strokeutil } from './paintutil/strokeutil.js'
import { FillUtil } from './paintutil/fillutil.js'

const linegap = 4;
class TextGraph extends baseunitgrah.BaseUnitGraph {
    constructor(gid) {
        super(gid);
        this.m_graphType = LGXEnums.LGXGraphType.TextGraph_type;

        //文本框中心。非真实文本中心。真实文本中心根据文本的对齐方式计算而得，不持久化
        var p = new Coord.PointPos();
        this.setPos(p);

        var action = new ActPkg.TextAction(this);
        this.setActionSvc(action);

        this.m_fontInfo = new LXCOM.LGXFontInfo();
        this.m_orignalText = "empty";
        this.m_formatText = "empty";
        this.m_hornAlign = "mid";
        this.m_vertAlign = "mid";
        this.dragCreateInitFlag = false;//刚刚由拖动后生成的图形对象的标签标志，此标志为true,要根据所属图形的区域zone重新计算本文本的坐标
        this.isTitleFlag = false;
        this.m_parentGraph = null;//文本标签所属图形对象
        this.width = 60;//文本框输入框宽度
        this.height = 15;//文本框输入框高度
        this.textWidth = 0;//纯文本宽度
        this.textHight = 0;//纯文本高度
        this._lineDef.linemode = LGXEnums.LGXLineMode.NoPen;
        this.exSetNewFlag = false;
        this.disLineTxtArr = [];//显示的文本行数
    }

    display(map, mapInfo, forClip) {
        if (!this.calScopeUseMap(map, mapInfo.getMapScale())){
            return ;
        }
        let x = this._position.x;
        let y = this._position.y;
        var cntScreenPT = CoordTRFUtil.world2Screen({ x, y }, mapInfo);

        var scaling = mapInfo.getLenthDisScale();
        map.fillStyle = this.m_fontInfo.fontColor.toHexString();
        this.activeFontOnCanvas(map, this.m_fontInfo, scaling);
        let rotv = this.getRadAngle();

        map.save();
        map.translate(cntScreenPT.x, cntScreenPT.y);
        map.rotate(-rotv);
        map.translate(-cntScreenPT.x, -cntScreenPT.y);
        this.paintZone(cntScreenPT, map, mapInfo);
        this.paintByAlignType(map, cntScreenPT, mapInfo);
        map.restore();

        if (this._selected) {
            this.displayFeaturePoint(map, mapInfo);
        }
        super.displayGraphScope(map, mapInfo);
        // this.displayTextActualZone(map,mapInfo);
        // console.log("txt wid heigt:"+this.textWidth+","+this.textHight);
        // console.log("leftTop:")
        // console.log(this.textLeftBottomPt);
        // console.log("pos:")
        // console.log(this._position);
        // console.log("width heigt:"+this.width+","+this.height);
    }

    displayTextActualZone(map, mapInfo) {
        var txtCnt = CoordTRFUtil.world2Screen(this._position, mapInfo);
        let scaling = mapInfo.getScaling();
        let halfWid = this.textWidth * scaling / 2;
        let halfhgt = this.textHight * scaling / 2;
        let left = txtCnt.x - halfWid;
        let top = txtCnt.y - halfhgt;
        map.beginPath();
        map.rect(left, top, halfWid * 2, halfhgt * 2);
        map.closePath();
        map.strokeStyle = "#ffff00";
        map.lineWidth = 1;
        map.stroke();
    }

    paintZone(cntScreenPT, map, mapInfo) {
        if (this._lineDef.linemode == LGXEnums.LGXLineMode.NoPen) {
            return;
        }
        let scaling = mapInfo.getScaling();
        let halfWid = this.width * scaling / 2;
        let halfhgt = this.height * scaling / 2;
        let left = cntScreenPT.x - halfWid;
        let top = cntScreenPT.y - halfhgt;
        map.beginPath();
        map.rect(left, top, halfWid * 2, halfhgt * 2);
        map.closePath();
        Strokeutil.active(this._lineDef, this, map, mapInfo);
        FillUtil.active(this._fillDef, map, this, mapInfo, false);
    }

    disInSymbol(transformInfo, map, mapInfo, forClip) {
        var scaling = mapInfo.getScaling();
        map.fillStyle = this.m_fontInfo.fontColor.toHexString();
        this.activeFontOnCanvas(map, this.m_fontInfo, scaling);
        var position = this.getPos();
        var x = position.x * scaling;
        var y = -position.y * scaling;
        var text = this.m_orignalText;
        var words = text.split(global.NEWTXTLINEMARK);
        for (var n = 0; n < words.length; n++) {
            var linetxt = words[n];
            var metrics = map.measureText(linetxt);
            var lineHeight = metrics.actualBoundingBoxAscent;
            map.fillText(linetxt, x, y + (n + 1) * lineHeight);
        }
    }

    paintByAlignType(map, textRectCnt, mapInfo) {
        var scaling = mapInfo.getLenthDisScale();
        let maxWidth = this.width * scaling;
        let maxHeight = this.height * scaling;

        var textSecs = this.m_orignalText.split(global.NEWTXTLINEMARK);

        let disLineTxtArr = this.calDisLineArr(map, textSecs, maxWidth);
        let disTextHgt = 0;
        for (var n = 0; n < disLineTxtArr.length; n++) {
            var linetxt = disLineTxtArr[n];
            var metrics = map.measureText(linetxt);
            var lineHeight = metrics.actualBoundingBoxAscent;
            disTextHgt += lineHeight;
        }

        disTextHgt += (disLineTxtArr.length - 1) * linegap;
        if (this.m_hornAlign == "mid") {
            map.textAlign = "center";
            let x = textRectCnt.x;
            this.paintByAlignType_horn(map, x, textRectCnt, disLineTxtArr, disTextHgt, maxHeight);
        }
        else if (this.m_hornAlign == "left") {
            map.textAlign = "left";
            let x = textRectCnt.x - maxWidth / 2;
            this.paintByAlignType_horn(map, x, textRectCnt, disLineTxtArr, disTextHgt, maxHeight);
        }
        else if (this.m_hornAlign == "right") {
            map.textAlign = "right";
            let x = textRectCnt.x + maxWidth / 2;
            this.paintByAlignType_horn(map, x, textRectCnt, disLineTxtArr, disTextHgt, maxHeight);
        }
    }

    paintByAlignType_horn(map, x, textRectCnt, disLineTxtArr, disTextHgt, maxHeigh) {
        if (disLineTxtArr.length < 1) {
            return;
        }

        // if (this.m_vertAlign == "mid") {
        //     var linetxt = disLineTxtArr[0];
        //     var metrics = map.measureText(linetxt);
        //     var lineHeight = metrics.actualBoundingBoxAscent;
        //     let y = textRectCnt.y - disTextHgt/2 + lineHeight;
        //     map.fillText(linetxt, x, y);

        //     y = y + lineHeight+linegap;
        //     for (var n = 1; n < disLineTxtArr.length; n++) {
        //         linetxt = disLineTxtArr[n];
        //         map.fillText(linetxt, x, y);
        //         metrics = map.measureText(linetxt);
        //         lineHeight = metrics.actualBoundingBoxAscent;
        //         y = y + lineHeight+linegap;
        //     }
        // }
        // else if (this.m_vertAlign == "top") {
        //     var linetxt = disLineTxtArr[0];
        //     var metrics = map.measureText(linetxt);
        //     var lineHeight = metrics.actualBoundingBoxAscent;
        //     let y = textRectCnt.y - maxHeigh/2 + lineHeight;
        //     map.fillText(linetxt, x, y);

        //     y = y + lineHeight+linegap;
        //     for (var n = 1; n < disLineTxtArr.length; n++) {
        //         linetxt = disLineTxtArr[n];
        //         map.fillText(linetxt, x, y);
        //         metrics = map.measureText(linetxt);
        //         lineHeight = metrics.actualBoundingBoxAscent;
        //         y = y + lineHeight+linegap;
        //     }
        // }
        // else if (this.m_vertAlign == "bottom") {
        //     var linetxt = disLineTxtArr[0];
        //     var metrics = map.measureText(linetxt);
        //     var lineHeight = metrics.actualBoundingBoxAscent;
        //     let y = textRectCnt.y + maxHeigh/2 - disTextHgt + lineHeight;
        //     map.fillText(linetxt, x, y);

        //     y = y + lineHeight+linegap;
        //     for (var n = 1; n < disLineTxtArr.length; n++) {
        //         linetxt = disLineTxtArr[n];
        //         map.fillText(linetxt, x, y);
        //         metrics = map.measureText(linetxt);
        //         lineHeight = metrics.actualBoundingBoxAscent;
        //         y = y + lineHeight+linegap;
        //     }
        // }

        let linetxt = disLineTxtArr[0];
        let metrics = map.measureText(linetxt);
        let lineHeight = metrics.actualBoundingBoxAscent;
        let y = textRectCnt.y;
        if (this.m_vertAlign == "mid") {
            y = textRectCnt.y - disTextHgt / 2 + lineHeight;
        }
        else if (this.m_vertAlign == "top") {
            y = textRectCnt.y - maxHeigh / 2 + lineHeight;
        }
        else if (this.m_vertAlign == "bottom") {
            y = textRectCnt.y + maxHeigh / 2 - disTextHgt + lineHeight;
        }
        map.fillText(linetxt, x, y);
        y = y + lineHeight + linegap;
        for (var n = 1; n < disLineTxtArr.length; n++) {
            linetxt = disLineTxtArr[n];
            map.fillText(linetxt, x, y);
            metrics = map.measureText(linetxt);
            lineHeight = metrics.actualBoundingBoxAscent;
            y = y + lineHeight + linegap;
        }
    }

    calDisLineArr(map, textSecs, maxWidth) {
        let txtLineArr = [];
        for (let i = 0; i < textSecs.length; i++) {
            let text = textSecs[i];
            this.calAutoWrapText(map, text, maxWidth, txtLineArr);
        }
        return txtLineArr;
    }

    calAutoWrapText(map, text, maxWidth, txtLineArr) {
        let words = text.split('');
        let line = '';

        for (let i = 0; i < words.length; i++) {
            let testLine = line + words[i];
            let metrics = map.measureText(testLine);
            let testWidth = metrics.width;

            if (testWidth > maxWidth && i > 0) {
                txtLineArr.push(line);
                line = words[i];
            } else {
                line = testLine;
            }
        }

        txtLineArr.push(line);
        return;
    }

    autoWrapText(map, linetxt, x, y, maxWidth, lineHeight) {
        let words = linetxt.split('');
        let line = '';

        for (let i = 0; i < words.length; i++) {
            let testLine = line + words[i];
            let metrics = map.measureText(testLine);
            let testWidth = metrics.width;

            if (testWidth > maxWidth && i > 0) {
                map.fillText(line, x, y);
                line = words[i];
                y = y + lineHeight + linegap;
            } else {
                line = testLine;
            }
        }

        map.fillText(line, x, y);
        return y;
    }



    calScope(mapscale) {
        this.m_calScopeFlag = false;
    }
    getLocalZone() {
        let rect = new LXCOM.LGXRect(0, 0, 0, 0);
        rect.clone(this._zone);
        let cnt = this._zone.getCnt();
        rect.left = rect.left - cnt.x;
        rect.right = rect.right - cnt.x;

        rect.top = rect.top - cnt.y;
        rect.bottom = rect.bottom - cnt.y;
        return rect;
    }

    calScopeUseMap(map, mapscale) {
        // console.log("text calScopeUseMap");
        if (this.m_calScopeFlag) {
            return true;
        }
        var text = this.m_orignalText;
        if (this.getFinish() == 1 &&(!text  || (text && text.length == 0))) {
            this.setUseful(0);
            return false;
        }
        this.activeFontOnCanvas(map, this.m_fontInfo, 1);

        var textSecs = this.m_orignalText.split(global.NEWTXTLINEMARK);
        let disLineTxtArr = this.calDisLineArr(map, textSecs, this.width);
        let disTextHgt = 0;
        let disTextWidth = -1;
        for (var n = 0; n < disLineTxtArr.length; n++) {
            var linetxt = disLineTxtArr[n];
            var metrics = map.measureText(linetxt);
            var lineHeight = metrics.actualBoundingBoxAscent;
            disTextHgt += lineHeight;

            let tempWid = metrics.width;
            if (disTextWidth < 0) {
                disTextWidth = tempWid;
            }
            else if (disTextWidth < tempWid) {
                disTextWidth = tempWid;
            }
        }

        disTextHgt += (disLineTxtArr.length - 1) * linegap;

        var position = this.getPosCopy();
        let textCnt = { x: 0, y: 0 };
        if (this.m_hornAlign == "mid") {
            textCnt.x = position.x;
        }
        else if (this.m_hornAlign == "left") {
            textCnt.x = position.x - this.width / 2 + disTextWidth / 2;
        }
        else if (this.m_hornAlign == "right") {
            textCnt.x = position.x + this.width / 2 - disTextWidth / 2;
        }
        textCnt.y = this.calVertPosByAlignType_vert(position, disTextHgt, this.height);


        let halfWid = disTextWidth / 2
        let halfhgt = disTextHgt / 2;

        this._zone.left = (textCnt.x - halfWid);
        this._zone.bottom = (textCnt.y - halfhgt);
        this._zone.right = (textCnt.x + halfWid);
        this._zone.top = (textCnt.y + halfhgt);

        this.m_calScopeFlag = true;
        return true;
    }

    calVertPosByAlignType_vert(textRectCnt, disTextHgt, rectHgt) {
        let y = textRectCnt.y;
        if (this.m_vertAlign == "mid") {
            y = textRectCnt.y;
        }
        else if (this.m_vertAlign == "top") {
            y = textRectCnt.y + rectHgt / 2 - disTextHgt / 2;
        }
        else if (this.m_vertAlign == "bottom") {
            y = textRectCnt.y - rectHgt / 2 + disTextHgt / 2;
        }
        return y;
    }

    displayFeaturePoint(map, mapInfo) {
        super.displayFeaturePoint(map, mapInfo);
    }

    distance(mousePt, scaling, mapscale) {
        let dis = -1;
        if (this.preCheckInScope(mousePt, scaling)) {
            if (this.m_parentGraph && this.m_parentGraph.m_graphType != LGXEnums.LGXGraphType.MoldGraph_type) {
                dis = -1;
            }
            else {
                dis = 0;
            }
        }
        return dis;
    }
    calculateSubKind(tPoint, scaling, mapscale) {
        if (!super.preCheckInScope(tPoint, scaling)) {
            return -1;
        }
        return 1;
    }

    movePosOffset(tOffset, modCmdInfo) {
        if (this._selKind < 1) {
            return;
        }
        var position = this.getPos();
        position.offset(tOffset.x, tOffset.y);
        this.translateGradientFill(tOffset);
    }
    getMainFeaturePTLst(tFeaturePTLst) {
        // var position = this.getPos();
        // var lenth = position.posList.length;
        // for (var i = 0; i < lenth; i++) {
        //     var pt = position.posList[i];
        //     var featurePT = new LXCOM.LGXPoint();
        //     featurePT.clone(pt);
        //     tFeaturePTLst.push(featurePT);
        // }
    }

    modifyAttribute(info, mapscale) {
        super.modifyCommonAttribute(info);
        this.m_orignalText = info.sOrigContent;
        this.m_formatText = info.sFormatContent;
        this.width = info.width;
        this.height = info.height;
        this.m_hornAlign = info.alignTypeH;
        this.m_vertAlign = info.alignTypeV;
        if (info.sOrigContent.length > 0 && this.getUseful() == 0) {
            this.setUseful(1);
        }

        this.m_fontInfo.fontsize = info.fontsize;
        // this.m_fontInfo.linespace = info.linespace;        // 行间距
        this.m_fontInfo.fontFamily = info.fontFamily;
        this.m_fontInfo.bold = info.bold;			  // 粗体
        this.m_fontInfo.italic = info.italic;		  // 倾斜
        this.m_fontInfo.underline = info.underline;	  // 带下划线
        this.m_fontInfo.strikeout = info.strikeout;	  // 中间有直线通过的文
        this.m_fontInfo.fontColor.setColorByValue(info.color);
        this.m_fontInfo.fontBKColor.setColorByValue(info.backColor);
        this.m_fontInfo.useBKFlag = info.useBKFlag;
        this.calScope(mapscale);
    }


    assignInfo(info) {
        super.assignInfo(info);
        this.m_gid = info.gid;
        this.type = info.type;
        this._position.clone(info.pos);
        this.modifyAttribute(info, 1);
        this.isTitleFlag = info.isTitleFlag;
    }

    toInfo() {
        var info = new textinfo.TextInfo();
        this.toInfo4InheritClass(info);
        info.color = this.m_fontInfo.fontColor.toValue();

        info.sFormatContent = this.m_formatText;
        info.sOrigContent = this.m_orignalText;

        info.x = this._position.x;
        info.y = this._position.y;
        info.alignTypeH = this.m_hornAlign;
        info.alignTypeV = this.m_vertAlign;

        info.fontsize = this.m_fontInfo.fontsize;
        info.fontFamily = this.m_fontInfo.fontFamily;
        info.bold = this.m_fontInfo.bold;
        info.italic = this.m_fontInfo.italic;
        info.underline = this.m_fontInfo.underline;
        info.strikeout = this.m_fontInfo.strikeout;
        info.isTitleFlag = this.isTitleFlag;
        info.width = this.width;
        info.height = this.height;

        let containerGraph = this.getContainer();
        if (this.isTitle && containerGraph) {
            let supRect = containerGraph.getZone();
            info.scope_left = supRect.left;
            info.scope_right = supRect.right;
        }

        if (this.m_parentGraph) {
            info.parentGID = this.m_parentGraph.m_gid;
        }
        return info;
    }

    getPosCopy() {
        let pos = new Coord.PointPos();
        pos.clone(this._position);
        return pos;
    }

    activeFontOnCanvas(map, fontinfo, scaling) {
        var canvasfont = " ";
        if (fontinfo.italic) {
            canvasfont += "italic ";
        }
        if (fontinfo.bold) {
            canvasfont += "bold ";
        }
        let tmp = Math.ceil(fontinfo.fontsize * scaling);
        var disFontSize = tmp + "px ";
        canvasfont += disFontSize
        canvasfont += fontinfo.fontFamily;
        map.font = canvasfont;
        return;
    }

    setText(v) {
        this.m_orignalText = v;
        this.m_calScopeFlag = false;
    }

    getText(v) { return this.m_orignalText; }
    getFormatText() { return this.m_formatText; }
    setFontInfo(v) { this.m_fontInfo.clone(v); }
    getFontInfo(v) { return this.m_fontInfo; }
    setTitleFlag(v) { this.isTitleFlag = v; }
    isTitle() { return this.isTitleFlag; }
    setParentGraph(v) { 
        this.m_parentGraph = v; 
        v.setLabel(this);
        this.resetLabelRect();
    }
    getParentGraph() { return this.m_parentGraph; }

    resetLabelSize() {
        if (this.m_parentGraph) {
            let localZone = this.m_parentGraph.getLocalZone();
            if (this.m_parentGraph.m_graphType == LGXEnums.LGXGraphType.MoldGraph_type) {
                this.width = localZone.width();
                this.height = this.m_fontInfo.fontsize * 2;
            }
            else {
                this.width = localZone.width();
                this.height = localZone.height();
            }
        }
    }

    resetLabelRect() {
        if (this.m_parentGraph) {
            let rect = this.m_parentGraph.getZone();
            let cntPt = rect.getCnt();
            this.width = rect.width();
            this.height = rect.height();
            this._position.x = cntPt.x;
            this._position.y = cntPt.y;
        }
        this.m_calScopeFlag = false;
    }


    translate(tOffset, mapscale, multiTransFlag) {
        this.setModified(1);
        this._position.offset(tOffset.x, tOffset.y);
        this.calScope(mapscale);
        this.notifyToObserver();
        this.translateGradientFill(tOffset);
        return 0;
    }

    resetLabelPosInRefRectBottom(map, refRect) {
        this.activeFontOnCanvas(map, this.m_fontInfo, 1);
        var txtWid = 0;
        var txtHgt = 0;
        var words = this.m_orignalText.split(global.NEWTXTLINEMARK);
        for (var n = 0; n < words.length; n++) {
            var linetxt = words[n];
            var metrics = map.measureText(linetxt);
            txtHgt = txtHgt + metrics.actualBoundingBoxAscent;
            txtWid = Math.max(txtWid, metrics.width);
        }

        this.textHight = txtHgt;
        this.textWidth = txtWid;
        this.width = refRect.width();
        this.height = refRect.height();
    }

    getTextSize() {
        let rect = new LXCOM.LGXRect(0, 0, 0, 0);

        rect.left = this._position.x - this.width / 2;
        rect.top = this._position.y + this.height / 2;
        rect.right = this._position.x + this.width / 2;
        rect.bottom = this._position.y - this.height / 2;

        return rect;
    }

    //复制粘贴时，从复制源对象复制属性到本图形对应属性----虚函数，由实体继承类实现
    copySubPropFromBuf(info, tx, ty) {
        this.copyCommnonPropFromBuf(info, tx, ty);
        this.m_hornAlign = info.alignTypeH;
        this.m_vertAlign = info.alignTypeV;
        this.m_orignalText = info.sOrigContent;
        this.m_formatText = info.sFormatContent;
        this.m_fontInfo.fontsize = info.fontsize;
        this.m_fontInfo.linespace = info.linespace;        // 行间距
        this.m_fontInfo.fontFamily = info.fontFamily;
        this.m_fontInfo.bold = info.bold;			  // 粗体
        this.m_fontInfo.italic = info.italic;		  // 倾斜
        this.m_fontInfo.underline = info.underline;	  // 带下划线
        this.m_fontInfo.strikeout = info.strikeout;	  // 中间有直线通过的文
        this.m_fontInfo.alignType = info.alignType;
        this.m_fontInfo.fontColor.setColorByValue(info.color);
        this.m_fontInfo.fontBKColor.setColorByValue(info.backColor);
        this.m_fontInfo.useBKFlag = info.useBKFlag;
    }
}

export default { TextGraph }
